/*** 
 * @Author: pengcheng
 * @Date: 2021-06-24 10:27:50
 * @LastEditTime: 2021-08-24 14:16:10
 * @LastEditors: pengcheng
 * @Description: 
 * @FilePath: /kylin-daq/src/DataCollection.h
 */
#ifndef DATACOLLECTIONMODULE_H
#define DATACOLLECTIONMODULE_H

#include <QtCore/QtCore>
#include <QtDBus/QtDBus>
#include <QtNetwork/QtNetwork>

#include "TransmitModule.h"
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/evp.h>

#include <iostream>
#include "BaseModule.h"
#include "KylinDaqCommon.h"

class DBusModule: public BaseModule
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "com.kylin.daq.interface")
public:
    /**
     * @brief dbus连接状态枚举
     * 
     */
    enum ConnectStatus
    {
        ConnectFailded = -1,
        ConnectSuccess = 1
    };
    /**
     * @brief UploadMessage返回值
     * 
     */
    enum UploadMessageReturnState{
        OK = 0,
        InvalidArgumentFormat = 1,
        InvalidTid = 2,
        InvalidUploadedMessageSha256 = 3,
        InvalidUploadedMessageSha256Decryption = 4,
        InvalidCreateTimeStamp = 5,
        DisableKey = 6
    };
    /**
     * @brief 设置上传状态放回值
     * 
     */
    enum SetState{
        inValid = 0,
        Valid = 1
    };
private:
    // dbus server
    /**
     * @brief dbus服务名
     * 
     */
    static constexpr const char *s_serverName = "com.kylin.daq";
    /**
     * @brief dbus路径名
     * 
     */
    static constexpr const char *s_objectPath = "/com/kylin/daq";
    /**
     * @brief dbus接口名
     * 
     */
    static constexpr const char *s_interfaceName = "com.kylin.daq.interface";
    /**
     * @brief 模块名
     * 
     */
    static constexpr const char *s_moduleName = "DBusModule";
    /**
     * @brief 传输模块名
     * 
     */
    static constexpr const char *s_transmitModuleName = "TransmitModule";
    /**
     * @brief 删除状态键
     * 
     */
    static constexpr const char *s_transmitModuleUploadStateKey = "UploadState";
    /**
     * @brief RSA私钥
     * 
     */
    static constexpr const char *privateKey =
        "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBc3VtTUxSRHZR\
        TW9LREJESTg0akpqc1A0Mk55V0pWVEZob2Jra3ZiT05jdExYTXVzCkZqNk8yVG5WWFN2elZVS0o0\
        amZKcE9pdlhKYTlQeWdsM2E0Z1BzSU40enNCMEdOY0trR3VsS2RrV2x6S3lWQ2wKZU84YkJzeko5\
        MG03N3FhemFoN2tQNE1JdFk1RXMwaUpKYkdKN1MxcERjMlJkNnVFQWJLaXJyRTFlNzlFTEd4agpu\
        VTdleTVpMkQxNlliaGREMGdpTWtkR0d6YkFwSk1mVkVSUU01NXorMFVqdS8zSFJhNFY3b3p2TGRP\
        RE5HUURaCnljSVNJd1RwS2xUd0YwcWs3QjY1YU1JSXp0NXZ4TitZcWFNRlppZFRLNzcxNjdqNEEx\
        Z3F3MG45bjlybWVXUGQKVmd3bnZ0bVV6eENZKzZNOUl6SkwyN3lqUVE1dVhkN0VXTE9ybndJREFR\
        QUJBb0lCQVFDQ0pGRExGMTV5Q29WMApjV0U3aFd6WVpNVkhPbTRkaWFTRlR1cEYzVEh5LzRZNlln\
        MHp3UjIzOWRHMmpKbmNreUlwWTl0U0VkQTkwWWluCndGU0xCSGFBTURoWjZqcFBrM2NmWmRmUVds\
        TXRTQUphbmtjL3lPNG43QitkdWd6eWRHQmQrVXFleUhvMVZ0K3kKYWprWktpUGlXdjNvQkhpa1RD\
        Y2g5UWRSZTZZajlLeVdKUFp4L1VIMjdBWXVJSW9vTjBUQXZ6b29TNVVxdnppegp6Q005WjlVRGgz\
        NjJrWEJMaElGL01hWW1iWGsxT1VoV1VyKzhhZVBoWjIwSmNMYjB5ZHpGUFFzTlNnMW5sVFVXCm4v\
        aE9QcEVyNytuOU4vakdjaTdDQnpsaHptY093cHhNRGRHTUhQdWhteHVpMGZ5ZU1XYTJDKytmL2NP\
        emdtYkgKNDVsV0JxL0JBb0dCQU92a2tMSEVFOTd5UWFIVFdiSUZFcG55MTFMWFpLcGJEdG94Sy8z\
        NXJLckJiL2lmVlNNQgpYSkx1YUxVQ29wWStwN01VZ2xxaXhvellmSHNiTTZtc3VmN1lZQk9wZlRz\
        eSt1WEI2cGo0MVBsV2pmQXJxOVQ2CnN2NU1Wd3dEM3pvRkNSaFA4WHlpc0VUM1k0V3RjNy9YcWFk\
        U3Q0TlpxV3NMWUFCeFh0bU5xdE9GQW9HQkFNSXAKbXhuUlpFNVFtOG02MkRoSjBrbVpEMUIwN1g5\
        bnB0VHRwM3pTM2FQUk9DT01JQUpQZ29JTG1EY0N5VDFHR3Q3bwpDYkxBZzN6N2JPYVowVkx1WE5T\
        UW5zLzI2dlYzbmNvaGJuNzl5Ni83MU9YVVg2YlFacENuakszNHVpWml0RngwCkRxNFB4amE3STJz\
        ZXlrS2JYejdvcHVwMzgxTEFsUHdSSWNqamhaSFRBb0dBWFFhdFBUMTdMSi9TM0RPU0dzOC8KVDdE\
        aDA0eVg2VXF4cDhCZWZmRVpjOW1IQThBcC9mMEtlZk5GSGFVbFl5VGdVNUlSK2haWlFMQWJIeDFT\
        R1diQgpqc3ZiejhVMldzTTNDS2Faa3F3R3FUSEdGZUhUQ05HNUJ1b3FKZFhkRVc5czc4YVBFRHpF\
        VU41U3hDUHNFc3JFCjMvU1I1RjNXbngxRVJjaHZ4RkhHL1ZVQ2dZRUFyWXJrajdvQmpxSXI3SzR0\
        Ym5wRkUvVlRvOVV2Smk0dUJxbDQKaDNBdUhLcjNJNGF1WVlKUm93emIrMmRwR1hSY3RobnQrVEJy\
        RmozZ0EyayttSUpteExPU3owemlpNDVqb1hRcQpRQ1YyZHBCL3BRRWlrWVk1OWxkYnZXL1FhbGpV\
        M3NINUVRa1dZSHI1MkZnSDdtclRRZlpPb3NtZDJidzZMZWJlCkxLRjRGSE1DZ1lCNUVJOXAwVnRn\
        czhXOFg0OTFHM3lkbTRLTzVPVSswMFFaMWJ2WHFBb0RqUDFjYmFZbGo5emQKWlFtZmc3andhNzdW\
        d2d2OWtiaEtYWEltTGZjbUhjeFl2ZlNKN1FKNzArb3dBVUJJK2p4akt2YUlNVXVkRFNZZgpmbjNI\
        bFBUOFdGV0tmTjJySUp4b1VtM1YxSlRXU285NHF1Si9xcHMrbE5aRUsxRHc5dmpZR3c9PQotLS0t\
        LUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=";
    /**
     * @brief 单例对象
     * 
     */
    static QScopedPointer<DBusModule> ms_instance;
    /**
     * @brief 被禁止的公共键
     *
     */
    QList<QString> m_disableCommonKey;
    /**
     * @brief 初始化被禁止的公共键
     *
     */
    void initDisableCommonKey();
    //	function
    //	rsa加密解密
    /**
     * @brief rsa加密
     * 
     * @param hasedValue 待加密值
     * @return QByteArray 加密结果
     */
    QByteArray encrypt(QByteArray hasedValue);
    /**
     * @brief rsa解密
     * 
     * @param hasedValue 待解密值
     * @return QByteArray 解密结果
     */
    QByteArray decrypt(QByteArray hasedValue);
    /**
     * @brief 打印加密错误
     * 
     */
    void evpError(void);
    /**
     * @brief 检测包信息
     * 
     * @param packInfo 包信息
     * @return UploadMessageReturnState 检测结果
     */
    UploadMessageReturnState checkPackageInfo(const QString &packInfo);
    /**
     * @brief  检测packageInfo中是否有无效字段
     * @param QJsonObject 包信息的json对象
     * @return UploadMessageReturnState 检测结果
     *
     */
    UploadMessageReturnState checkPackageInfoInvalidKey(const QJsonObject &packageInfoJsonObj);
    /**
     * @brief 检测hase值是否正常
     * 
     * @param information information值
     * @param hasedValue hase值
     * @return UploadMessageReturnState 检测结果
     */
    UploadMessageReturnState checkHashedValue(const QString &information,const QString &hasedValue);
    /**
     * @brief 检测information中是否包含必要字段
     * 
     * @param uploadedMessage 上传消息
     * @return UploadMessageReturnState 检测结果
     */
    UploadMessageReturnState checkUploadedMessage(const QString &uploadedMessage);
    /**
     * @brief  检测uploadedMessage中是否有无效字段
     * @param QJsonObject 待上传消息的json对象
     * @return UploadMessageReturnState 检测结果
     *
     */
    UploadMessageReturnState checkUploadedMessageInvalidKey(const QJsonObject &uploadedMessageJsonObj);
    /**
      * @brief  检测uploadedMessage中时间戳是否有效
      * @param QJsonObject uploadedMessage的json对象
      * @return UploadMessageReturnState 检测结果
      *
      */
    UploadMessageReturnState checkUploadedMessageTimeStampState(const QJsonObject &uploadedMessageJsonObj);
    /**
     * @brief 依据packInfo创建Tid
     * 
     * @param packInfo 包信息
     * @return QString tid
     */
    QString createPackInfoId(const QString &packInfo);
    /**
     * @brief 获取packInfo中的tid
     * 
     * @param packageInfo 包信息
     * @return QString tid
     */
    QString getPackageInfoTid(const QString &packageInfo);
    /**
     * @brief 填充source信息
     * 
     * @param packageInfo 包信息
     * @param tid tid
     * @param newTid 新的tid
     * @return QString 填充完的结果
     */
    QString fillSource(const QString &packageInfo, const QString &tid, const QString &newTid);
    /**
     * @brief Create a Valid Message object
     * 
     */
    void createValidMessage();
    /**
     * @brief 
     * 
     * @param source 
     * @param uploadedMessage 
     * @return QString 
     */
    QString fillValidInfo(const QString &source,const QString &uploadedMessage);
    /**
     * @brief Construct a new DBusModule object
     * 
     * @param parent 
     */
    explicit DBusModule(QObject *parent = nullptr);
public:
    /**
     * @brief Destroy the DBusModule object
     * 
     */
    virtual ~DBusModule();
    /**
     * @brief instance function
     * 
     * @return DBusModule* 
     */
    static DBusModule *instance(void);
public slots:
    /**
     * @brief 获取上传状态
     * 
     * @return int 上传状态
     */
    int GetUploadState();
    /**
     * @brief 设置上传状态
     * 
     * @param setState 被设置的上传状态
     * @return int 设置结果
     */
    int SetUploadState(int setState);
    /**
     * @brief 上传信息
     * 
     * @param packageInfo 包信息
     * @param uploadedMessage 待上传信息
     * @param uploadedMessageSha256 待上传信息散列值
     * @param retTid 返回的tid
     * @return int 返回状态
     */
    int UploadMessage(const QString &packageInfo, const QString &uploadedMessage, const QString &uploadedMessageSha256, QString &retTid);
    /**
     * @brief 依据包名和消息类型在数据库中查询tid
     * 
     * @param packageName 包名
     * @param messageType 消息类型
     * @return QString tid
     */
    QString GetTid(const QString &packageName, const QString &messageType);
    virtual void updateProperty(const QJsonObject &conf,const QJsonObject &defaultConf);
signals:
    /**
     * @brief 发送埋点数据
     * 
     * @param info 埋点数据
     */
    void saveInfo(const QString &info);
    /**
     * @brief 发送tid数据
     * 
     * @param info tid
     */
    void saveTid(const QString &info);
    /**
     * @brief 检测tid是否存在
     * 
     * @param info tid
     * @param existState tid是否存在于数据库
     */
    void checkTid(const QString &info, bool &existState);
    /**
     * @brief 存储上传状态配置
     * 
     * @param moduleName 模块名
     * @param key 键
     * @param value 值
     */
    void saveUploadState(const QString &moduleName, const QString &key, const QVariant &value);

    //	property
private:
    Q_PROPERTY(UploadState uploadState READ uploadState WRITE setUploadState NOTIFY uploadStateChanged)
    UploadState m_uploadState;
public:
    UploadState uploadState() const
    {
        return m_uploadState;
    }
public slots:
    void setUploadState(UploadState uploadState)
    {
        if (m_uploadState == uploadState)
            return;

        m_uploadState = uploadState;
        emit uploadStateChanged(m_uploadState);
        emit saveUploadState(QString(s_transmitModuleName),QString(s_transmitModuleUploadStateKey),UploadState(m_uploadState));
    }
signals:
    void uploadStateChanged(UploadState uploadState);
};

#endif // TEST_H
